﻿using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity;

namespace Giraffe.Core.Common
{
    public static class ObjectProvider
    {
        private static IUnityContainer _unityContainer;

        public static IUnityContainer Container
        {
            set
            {
                _unityContainer = value;
            }
        }

        public static void RegisterType<T>(bool isSingleton)
        {
            if (isSingleton)
            {
                _unityContainer.RegisterType<T>(new ContainerControlledLifetimeManager());
            }
            else
            {
                _unityContainer.RegisterType<T>();
            }
        }

        public static void RegisterType<T>()
        {
            RegisterType<T>(false);
        }


        public static void RegisterType<T>(string name, bool isSingleton)
        {
            if (isSingleton)
            {
                _unityContainer.RegisterType<T>(name, new ContainerControlledLifetimeManager());
            }
            else
            {
                _unityContainer.RegisterType<T>(name);
            }
        }

        public static void RegisterInstance<T>(T instance)
        {
            _unityContainer.RegisterInstance(instance);
        }

        public static T Resolve<T>()
        {
            //InitializeInterceptors<T>();
            T obj = _unityContainer.Resolve<T>();
            return obj;
        }

        public static T Resolve<T>(string name)
        {
            //InitializeInterceptors<T>();

            T obj = _unityContainer.Resolve<T>(name);
            return obj;
        }

        //private static void InitializeInterceptors<T>()
        //{
        //    Type type = typeof(T);
        //    Interception interception = _unityContainer
        //        .Configure<Interception>();
        //    if (type.IsInterface)
        //    {
        //        interception.SetDefaultInterceptorFor(typeof(T), new InterfaceInterceptor());
        //    }
        //    else if (type.IsAssignableFrom(typeof(MarshalByRefObject)))
        //    {
        //        interception.SetDefaultInterceptorFor(typeof(T), new TransparentProxyInterceptor());
        //    }

        //    //TODO Uncomment this when Unity 2.0 will be released
        //    //            else
        //    //            {
        //    //                interception.SetDefaultInterceptorFor(typeof(T), new VirtualMethodInterceptor());
        //    //
        //    //            }


        //}

        public static IEnumerable<T> ResolveAll<T>()
        {
            return _unityContainer.ResolveAll<T>();
        }

        public static T Resolve<T>(params Tuple<string, object>[] overrides)
        {
            var resolverOverrides = new ParameterOverrides();
            foreach (Tuple<string, object> @override in overrides)
            {
                resolverOverrides.Add(@override.Item1, @override.Item2);
            }
            
            T obj = _unityContainer.Resolve<T>(resolverOverrides);
            return obj;
        }
    }
}
